﻿using System.Text;
using MarkdownSharp;
using Ude;

namespace NiuX.AspNetCore.MiniWebApi.Core.Middlewares;

public class MarkDownViewerMiddleware
{
    private readonly RequestDelegate _next;

    public MarkDownViewerMiddleware(RequestDelegate next)
    {
        this._next = next;
    }

    /// <summary>
    /// 检测流的编码
    /// </summary>
    /// <param name="stream"></param>
    /// <returns></returns>
    private static string DetectCharset(Stream stream)
    {
        CharsetDetector charDetector = new();
        charDetector.Feed(stream);
        charDetector.DataEnd();
        string charset = charDetector.Charset ?? "UTF-8";
        stream.Position = 0;
        return charset;
    }

    /// <summary>
    /// 读取文本内容
    /// </summary>
    /// <param name="stream"></param>
    /// <returns></returns>
    private static async Task<string> ReadText(Stream stream)
    {
        string charset = DetectCharset(stream);
        using var reader = new StreamReader(stream, Encoding.GetEncoding(charset));
        return await reader.ReadToEndAsync();
    }

    public async Task InvokeAsync(HttpContext context)
    {
        string path = context.Request.Path.Value ?? "";
        if (!path.EndsWith(".md"))
        {
            await _next(context);
            return;
        }
        var file = new FileInfo($@"{System.Environment.CurrentDirectory}\docs\{path}");
        //new FileStream(file.OpenRead(),FileMode.Open)
        if (!file.Exists)
        {
            await _next(context);
            return;
        }
        context.Response.ContentType = $"text/html;charset=UTF-8";
        context.Response.StatusCode = 200;
        //string cacheKey = nameof(MarkDownViewerMiddleware)
        //    + path + file.LastWriteTime;
        //var html = await memCache.GetOrCreateAsync(cacheKey, async ce =>
        //{
        //    ce.AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(1);
        //    await using var stream = file.OpenRead();
        //    string text = await ReadText(stream);
        //    Markdown markdown = new Markdown();
        //    return markdown.Transform(text);
        //});

        await using var stream = file.OpenRead();
        string html = await ReadText(stream);
        Markdown markdown = new Markdown();
        html = markdown.Transform(html);

        var text = $@"<!doctype html>
<html>

<head>
    <meta charset=""utf-8"">
    <meta name=""viewport"" content=""width=device-width, initial-scale=1, minimal-ui"">
    <title>GitHub Markdown CSS demo</title>
    <meta name=""color-scheme"" content=""light dark"">
    <link rel=""stylesheet"" href=""/github-markdown.css"">
    <style>
        body {{
            box-sizing: border-box;
            min-width: 200px;
            max-width: 980px;
            margin: 0 auto;
            padding: 45px;
        }}

        @media (prefers-color-scheme: dark) {{
            body {{
                background-color: #0d1117;
            }}
        }}
    </style>
    <link rel=""stylesheet"" href=""https://cdnjs.cloudflare.com/ajax/libs/github-fork-ribbon-css/0.2.3/gh-fork-ribbon.min.css"">
    <style>
        .github - fork - ribbon:before {{
            background - color: #121612;
        }}
    </style >
</head >

<body>
    <article class=""markdown-body"">
{html}
    </article>
</body>
</html>";

        await context.Response.WriteAsync(text);
    }
}